home *** CD-ROM | disk | FTP | other *** search
/ System Booster / System Booster.iso / Commodities / KeyClick / src / keyclick.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-09-27  |  5.9 KB  |  246 lines

  1. /*
  2.  *    KeyClick v1.0
  3.  *
  4.  *    Adds a clicking sound to each keypress. Yes, it's not the first
  5.  *    program of its kind...
  6.  *
  7.  *    Martin W. Scott, 22/05/92.
  8.  */
  9.  
  10. #include <exec/types.h>
  11. #include <exec/exec.h>
  12. #include <devices/input.h>
  13. #include <devices/inputevent.h>
  14. #include <intuition/intuition.h>
  15. #include <libraries/gadtools.h>
  16. #include <proto/exec.h>
  17. #include <proto/dos.h>
  18. #include <proto/intuition.h>
  19. #include <proto/gadtools.h>
  20. #include "beep.h"
  21. #include "window.h"
  22.  
  23. #define register        /* let optimiser decide */
  24.  
  25. #define CONFIG_FILE    "S:KeyClick.config"
  26.  
  27. #define TASK_PRIORITY     19    /* always get to beep */
  28. #define HANDLER_PRIORITY 70    /* avoid (most) manufactured input-events */
  29.  
  30. typedef struct {
  31.     struct Task     *buddy;    /* task starting handler */
  32.     ULONG        sigmask;    /* signal to give parent */
  33. } GLOBAL_DATA;
  34.  
  35.  
  36. struct InputEvent __regargs *myhandler(struct InputEvent *, register GLOBAL_DATA *);
  37.  
  38.  
  39. /*** HANDLER CODE ***/
  40.  
  41. struct InputEvent __regargs *myhandler(ev,gptr)
  42. struct InputEvent *ev;
  43. register GLOBAL_DATA *gptr;
  44. {
  45.     register struct InputEvent *ep;
  46.  
  47.     for (ep = ev; ep; ep = ep->ie_NextEvent)
  48.     {
  49.     if ((ep->ie_Class == IECLASS_RAWKEY) && !(ep->ie_Code & IECODE_UP_PREFIX))
  50.         Signal(gptr->buddy,gptr->sigmask);
  51.     }
  52.  
  53.     return (ev);
  54. }
  55.  
  56.  
  57. /*** GLOBAL DATA STRUCTURES ***/
  58. struct IntuitionBase *IntuitionBase;
  59. struct GadToolsBase *GadToolsBase;
  60. struct MsgPort *inputPort;
  61. struct IOStdReq *inputRequest;
  62. struct Interrupt handlerstuff;
  63. GLOBAL_DATA global;
  64.  
  65. LONG click_vol = 32;        /* initial volume - must be multiple of 2 */
  66. LONG click_freq = 2300;        /* and frequency - must be a multiple of 25 */
  67. LONG click_on = 1;        /* beeping on or off? */
  68.  
  69. BOOL prefsloaded;        /* disk-resident preferences loaded ok? */
  70.  
  71. void _main(char *);     /* prototype for _main */
  72.  
  73. /*** MAIN PROGRAM ***/
  74.  
  75. void CloseLibs()
  76. {
  77.     if (IntuitionBase) CloseLibrary(IntuitionBase);
  78.     if (GadToolsBase) CloseLibrary(GadToolsBase);
  79. }
  80.  
  81. BOOL OpenLibs()
  82. {
  83.     if ((IntuitionBase = (void *)OpenLibrary("intuition.library",37L)) &&
  84.         (GadToolsBase =  (void *)OpenLibrary("gadtools.library",37L)))
  85.         return TRUE;
  86.  
  87.     CloseLibs();
  88.     return FALSE;
  89. }
  90.  
  91. #define KCLK    0x4b434c4b
  92. void LoadConfig()
  93. {
  94.     ULONG tmp[3];
  95.     BPTR fh;
  96.  
  97.     if (fh = Open(CONFIG_FILE, MODE_OLDFILE))
  98.     {
  99.         if ((Read(fh, tmp, 12) == 12) && tmp[0] == KCLK)
  100.         {
  101.             click_vol = tmp[1];
  102.             click_freq = tmp[2];
  103.             prefsloaded = TRUE;
  104.         }
  105.         Close(fh);
  106.     }    
  107. }
  108.  
  109. void SaveConfig()
  110. {
  111.     ULONG tmp[3];
  112.     BPTR fh;
  113.  
  114.     if (fh = Open(CONFIG_FILE, MODE_NEWFILE))
  115.     {
  116.         tmp[0] = KCLK;
  117.         tmp[1] = click_vol;
  118.         tmp[2] = click_freq;
  119.  
  120.         Write(fh, tmp, 12);
  121.         Close(fh);
  122.     }
  123. }
  124.  
  125. void _main()            /* beep on keypresses */
  126. {
  127.     WORD sigbit = -1;        /* signal for our handler to use */
  128.     LONG oldpri;        /* task priority before we change it */
  129.     LONG sigmask;        /* signals we're waiting for */
  130.     LONG signals;        /* and what we received */
  131.  
  132.  
  133.     /*** Open/allocate libraries, ports, IO requests, signals, Window ***/
  134.  
  135.     LoadConfig();        /* load user-settings */
  136.  
  137.     if ((inputPort = CreateMsgPort()) &&
  138.     (inputRequest = CreateIORequest(inputPort, sizeof(struct IOStdReq))) &&
  139.     ((sigbit = AllocSignal(-1)) != -1) &&
  140.     (AllocAudio() == TRUE) &&
  141.     OpenLibs() &&
  142.     !SetupScreen() &&
  143.     !OpenClickWindow())
  144.     {
  145.     if (prefsloaded) ZipWindow(ClickWnd);
  146.  
  147.     global.buddy = FindTask(NULL);      /* initialize liason structure */
  148.     global.sigmask = 1 << sigbit;
  149.     oldpri = SetTaskPri(global.buddy, TASK_PRIORITY);
  150.  
  151.     handlerstuff.is_Data = (APTR)&global;           /* set up handler */
  152.     handlerstuff.is_Code = (void *)(myhandler);
  153.     handlerstuff.is_Node.ln_Pri = HANDLER_PRIORITY;
  154.  
  155.     if (!OpenDevice("input.device",0,inputRequest,0))
  156.     {
  157.         inputRequest->io_Command = IND_ADDHANDLER;
  158.         inputRequest->io_Data = (APTR)&handlerstuff;
  159.         DoIO(inputRequest);                         /* install handler */
  160.  
  161.         sigmask = global.sigmask | (1 << ClickWnd->UserPort->mp_SigBit);
  162.  
  163.         for (;;)        /** wait for messages **/
  164.         {
  165.         struct IntuiMessage *msg;
  166.         struct Gadget   *gadget;
  167.         struct PropInfo *pi;
  168.         ULONG           class;
  169.         UWORD        code;
  170.  
  171.         signals = Wait(sigmask);
  172.  
  173.         if (signals & global.sigmask)
  174.         {
  175.             if (click_on)
  176.             {
  177.                 beep(click_vol,click_freq);
  178.                 Delay(1);   /* avoid ugly sound when key repeating */
  179.             }
  180.         }
  181.         if (!(signals ^ global.sigmask))    /* no idcmp */
  182.             continue;
  183.  
  184.         while (msg = GT_GetIMsg(ClickWnd->UserPort))
  185.         {
  186.             class = msg->Class;
  187.             code = msg->Code;
  188.             gadget = (struct Gadget *)msg->IAddress;
  189.             GT_ReplyIMsg(msg);
  190.  
  191.             if (class & SLIDERIDCMP)    /* change of settings */
  192.             {
  193.             if (gadget->GadgetID == GD_Vol)
  194.             {
  195.                 pi = (struct PropInfo *) ClickGadgets[GDX_Vol]->SpecialInfo;
  196.                 click_vol = ((pi->HorizPot+1) * 64) / 0xFFFF;
  197.                 beep(click_vol,click_freq);
  198.             }
  199.             else if (gadget->GadgetID == GD_Freq)
  200.             {
  201.                 pi = (struct PropInfo *) ClickGadgets[GDX_Freq]->SpecialInfo;
  202.                 click_freq = ((pi->HorizPot+1) * 2300) / 0xFFFF + 100;
  203.                 beep(click_vol,click_freq);
  204.             }
  205.             }
  206.  
  207.             if (class == GADGETUP)    /* could be sliders, but ignore if so */
  208.             {
  209.             if (gadget->GadgetID == GD_Toggle)
  210.                 click_on ^= 1;
  211.             else if (gadget->GadgetID == GD_Save)
  212.                 SaveConfig();
  213.             }
  214.             else if (class == REFRESHWINDOW)
  215.             {
  216.             GT_RefreshWindow( ClickWnd, NULL );
  217.             }
  218.             else if (class == CLOSEWINDOW)
  219.             goto byebye;
  220.  
  221.         } /* while */
  222.  
  223.         } /* for (;;) */
  224. byebye:
  225.         inputRequest->io_Command = IND_REMHANDLER;
  226.         inputRequest->io_Data = (APTR)&handlerstuff;
  227.         DoIO(inputRequest);                         /* remove handler */
  228.         CloseDevice(inputRequest);
  229.     }
  230.     else PutStr("Can't open input.device\n");
  231.  
  232.     SetTaskPri(global.buddy, oldpri);    /* restore task's priority */
  233.     }
  234.     else PutStr("Can't alloc resources\n");
  235.  
  236.     /*** Close/free what we opened/allocated ***/
  237.  
  238.     CloseClickWindow();
  239.     CloseDownScreen();
  240.     CloseLibs();
  241.     FreeAudio();
  242.     if (inputRequest) DeleteIORequest(inputRequest);
  243.     if (inputPort) DeleteMsgPort(inputPort);
  244.     if (sigbit != -1) FreeSignal(sigbit);
  245. }
  246.